package org.huoran.sakamichi.main.netty.webSocket;


import com.alibaba.fastjson.JSONObject;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.apache.commons.lang3.StringUtils;
import org.huoran.sakamichi.main.netty.webSocket.bean.MessageContent;
import org.huoran.sakamichi.main.netty.webSocket.bean.MessageDto;
import org.huoran.sakamichi.main.netty.webSocket.bean.MessageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    final Logger logger = LoggerFactory.getLogger(HttpRequestHandler.class);

    private final String wsUri;

    public HttpRequestHandler(String wsUri) {
        this.wsUri = wsUri;
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        // 以"/"分割url验证ws以及用户名
        String[] spliteStr = request.getUri().split("/");
        String location = ctx.channel().remoteAddress().toString();
        if(spliteStr.length == 3){
            if (StringUtils.isNoneEmpty(spliteStr[1]) && spliteStr[1].equals(wsUri)) {
                String name = spliteStr[2];
                if(StringUtils.isNotEmpty(name)){
                    name = ClientManager.getInstance().put(name, location);
                    ctx.fireChannelRead(request.retain().setUri(wsUri));
                    ChannelGroup channels = TextWebSocketFrameHandler.getChannels();
                    Channel incoming = ctx.channel();
                    // 给当前所有客户端推送新客户端的加入消息
                    for (Channel channel : channels) {
                        if (channel != incoming){
                            MessageContent messageContent = new MessageContent();
                            messageContent.setFrom(name);
                            MessageDto messageDto = new MessageDto();
                            messageDto.setType(MessageType.MEMBER_JOIN);
                            messageDto.setContent(messageContent);
                            channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(messageDto)));
                        } else {
                            MessageContent messageContent = new MessageContent();
                            messageContent.setBody(name);
                            MessageDto messageDto = new MessageDto();
                            messageDto.setType(MessageType.UNREPEATED_NAME);
                            messageDto.setContent(messageContent);
                            channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(messageDto)));
                        }
                    }
                    logger.info("websocket client added : " + location + " / " + name);
                }
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        cause.printStackTrace();
        ctx.close();
        logger.info("websocket client exception : " + ctx.channel().localAddress());
    }
}